package org.zjvis.datascience.common.util.db;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.sql.Wrapper;
import lombok.Getter;
import lombok.Setter;

import java.util.Map;

/**
 * @description SQL聚合函数包装类
 * @date 2020-09-02
 */
@Getter
@Setter
public class FunctionWrapper extends Wrapper {

    /**
     * field - function map
     * function中最终需要填入字段名的地方用{}，其余按sql中正常写法。如：a(b({}))
     */
    private Map<String, String> functions;

    public FunctionWrapper(Character wrapQuote) {
        super(wrapQuote);
    }

    public FunctionWrapper(Character preWrapQuote, Character sufWrapQuote) {
        super(preWrapQuote, sufWrapQuote);
    }

    public static FunctionWrapper build(Wrapper wrapper) {
        return new FunctionWrapper(wrapper.getPreWrapQuote(), wrapper.getSufWrapQuote());
    }

    public FunctionWrapper addFunctions(Map<String, String> functions) {
        setFunctions(functions);
        return this;
    }

    @Override
    public String wrap(String field) {
        String origin = wrapWithQuote(field);

        if (CollectionUtil.isEmpty(functions) || !functions.containsKey(origin)) {
            return origin;
        }

        // 需要改名成原来名称
        return StrUtil.format(functions.get(origin) + "  AS {}", field, origin);
    }

    private String wrapWithQuote(String field) {
        //如果已经包含包装的引号，返回原字符
        if(StrUtil.isSurround(field, super.getPreWrapQuote(), super.getSufWrapQuote())){
            return field;
        }

        //如果字段中包含通配符或者括号（字段通配符或者函数），不做包装
        if(StrUtil.containsAnyIgnoreCase(field, "*", "(", " ", " as ")) {
            return field;
        }
        return StrUtil.format("{}{}{}", super.getPreWrapQuote(), field, super.getSufWrapQuote());
    }

}
